package dao

import (
	"chat_srv/basic/config"
	chat "chat_srv/basic/proto"
	model "chat_srv/handler/model/user"
	"context"
	"fmt"
	"time"
)

// 关注
func UserFollow(_ context.Context, in *chat.UserFollowReq) (*model.UserFollow, error) {
	// 参数校验
	if in.FormUserId == 0 || in.ToUserId == 0 {
		return nil, fmt.Errorf("参数不能为空")
	}
	// 查询用户关注
	var userFollow model.UserFollow
	if err := userFollow.GetUserFollow(&model.UserFollow{
		FromUserId: uint(in.FormUserId),
		ToUserId:   uint(in.ToUserId),
		Status:     1,
	}); err != nil {
		return nil, fmt.Errorf("查询用户关注失败: %v", err)
	}
	if userFollow.Id != 0 {
		return nil, fmt.Errorf("用户已关注")
	}

	// 开启事务
	tx := config.DB.Begin()
	defer func() {
		if tx.Error != nil {
			tx.Rollback()
		}
	}()

	// 关注用户
	userFollow = model.UserFollow{
		FromUserId: uint(in.FormUserId),
		ToUserId:   uint(in.ToUserId),
	}
	if err := userFollow.Create(tx); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("关注用户失败: %v", err)
	}

	// 更新用户关注数
	var user model.User
	if err := user.AddFollowCount(tx, &model.User{
		Id: int64(in.FormUserId),
	}); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("更新用户关注数失败: %v", err)
	}
	// 更新用户粉丝数
	if err := user.AddFansCount(tx, &model.User{
		Id: int64(in.ToUserId),
	}); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("更新用户粉丝数失败: %v", err)
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("提交事务失败: %v", err)
	}

	return &userFollow, nil
}

// 取消关注
func UserNotFollow(_ context.Context, in *chat.UserNotFollowReq) (*model.UserFollow, error) {
	// 参数校验
	if in.FormUserId == 0 || in.ToUserId == 0 {
		return nil, fmt.Errorf("参数不能为空")
	}
	// 查询用户关注
	var userFollow model.UserFollow
	if err := userFollow.GetUserFollow(&model.UserFollow{
		FromUserId: uint(in.FormUserId),
		ToUserId:   uint(in.ToUserId),
		Status:     1,
	}); err != nil {
		return nil, fmt.Errorf("查询用户关注失败: %v", err)
	}
	if userFollow.Id == 0 {
		return nil, fmt.Errorf("用户未关注")
	}

	// 开启事务
	tx := config.DB.Begin()
	defer func() {
		if tx.Error != nil {
			tx.Rollback()
		}
	}()

	// 取消关注
	if err := userFollow.CancelFollow(tx, &model.UserFollow{
		Id: userFollow.Id,
	}); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("取消关注失败: %v", err)
	}

	// 更新用户关注数
	var user model.User
	if err := user.SubFollowCount(tx, &model.User{
		Id: int64(in.FormUserId),
	}); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("更新用户关注数失败: %v", err)
	}
	// 更新用户粉丝数
	if err := user.SubFansCount(tx, &model.User{
		Id: int64(in.ToUserId),
	}); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("更新用户粉丝数失败: %v", err)
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("提交事务失败: %v", err)
	}

	return &userFollow, nil
}

// 发送好友申请
func Application(_ context.Context, in *chat.ApplicationReq) (*model.FriendApplication, error) {
	// 请求参数
	if in.FormUserId == 0 || in.ToUserId == 0 {
		return nil, fmt.Errorf("参数不能为空")
	}
	// 限制申请次数
	key := fmt.Sprintf("friend_application_%d_%d", in.FormUserId, in.ToUserId)
	count, _ := config.Rdb.Get(config.Ctx, key).Int()
	if count > 0 {
		return nil, fmt.Errorf("一天内只能发送一次好友申请")
	}
	// 添加
	application := model.FriendApplication{
		ApplicantId: uint(in.FormUserId),
		RecipientId: uint(in.ToUserId),
		Status:      1,
		Greeting:    in.Greeting,
	}
	if err := application.Create(); err != nil {
		return nil, fmt.Errorf("好友申请失败")
	}
	incr := config.Rdb.Incr(config.Ctx, key).Val()
	if incr > 0 {
		// 增加申请次数
		config.Rdb.Expire(config.Ctx, key, time.Hour*24)
	}
	return &application, nil
}

// 同意好友申请
func AcceptApplication(_ context.Context, in *chat.AcceptApplicationReq) (*model.FriendApplication, error) {
	// 参数校验
	if in.ApplicationId == 0 {
		return nil, fmt.Errorf("参数不能为空")
	}
	// 查询好友申请
	var application model.FriendApplication
	if err := application.GetFriendApplication(&model.FriendApplication{
		Id: uint(in.ApplicationId),
	}); err != nil {
		return nil, fmt.Errorf("好友申请查询失败: %v", err)
	}
	if application.Status == 0 {
		return nil, fmt.Errorf("好友申请不存在")
	}

	if uint64(application.RecipientId) != in.UserId {
		return nil, fmt.Errorf("当前用户无权限")
	}

	// 同意好友申请
	if err := application.Update(&model.FriendApplication{
		Id: uint(in.ApplicationId),
	}, 2); err != nil {
		return nil, fmt.Errorf("好友申请同意失败: %v", err)
	}

	return &application, nil
}

// 拒绝好友申请
func RejectApplication(_ context.Context, in *chat.RejectApplicationReq) (*model.FriendApplication, error) {
	// 参数校验
	if in.ApplicationId == 0 {
		return nil, fmt.Errorf("参数不能为空")
	}
	// 查询好友申请
	var application model.FriendApplication
	if err := application.GetFriendApplication(&model.FriendApplication{
		Id: uint(in.ApplicationId),
	}); err != nil {
		return nil, fmt.Errorf("好友申请查询失败: %v", err)
	}
	if application.Status == 0 {
		return nil, fmt.Errorf("好友申请不存在")
	}
	if uint64(application.RecipientId) != in.UserId {
		return nil, fmt.Errorf("当前用户无权限")
	}
	// 拒绝好友申请
	if err := application.Update(&model.FriendApplication{
		Id: uint(in.ApplicationId),
	}, 3); err != nil {
		return nil, fmt.Errorf("好友申请拒绝失败: %v", err)
	}

	return &application, nil
}
